import time
import uuid

from flask import request
from flask_restful import Resource

from commons.models import Player, Account, UserToken
from commons.rs_code import rscode_response, RsCode
from commons.tools import safe_commit, check_safe_str, check_safe_nickname
from db import db
from views.user.services import init_player


class UserLoginView(Resource):
    def post(self):
        """
        登录接口
        """
        username = request.json.get("username")
        password = request.json.get("password")

        if not username or not password:
            return rscode_response(RsCode.ARGS_ERROR)

        account = Account.query.filter(Account.username == username, Account.password == password).scalar()
        if not account:
            return rscode_response(RsCode.ARGS_ERROR, new_msg="账号或密码不正确")

        player = Player.query.filter(Player.account_id == account.id).scalar()

        token = UserToken.query.filter(UserToken.player_id == player.id).scalar()
        if token:
            token.token = uuid.uuid4().hex
            token.expires = time.time() + 7 * 24 * 60 * 60
        else:
            token = UserToken(token=uuid.uuid4().hex, user_id=account.user_id, expires=time.time() + 7 * 24 * 60 * 60)
            db.session.add(token)

        account.last_login_time = time.time()
        account.last_login_ip = request.remote_addr

        if not safe_commit(db):
            return rscode_response(RsCode.SERVER_BUSY)

        return rscode_response(data={
            "token": token.token
        })


class UserRegisterView(Resource):
    def post(self):
        """
        注册
        """
        username = request.json.get("username")
        password = request.json.get("password")
        nickname = request.json.get("nickname")
        gender = request.json.get("gender")

        # 校验参数
        if not all([username, password, nickname, gender]):
            return rscode_response(RsCode.ARGS_ERROR)

        if not 8 <= len(username) <= 16 or not 8 <= len(password) <= 16:
            return rscode_response(RsCode.ARGS_ERROR, new_msg="账号和密码的长度在8~16个字符之间")

        if not check_safe_str(username) or not check_safe_str(password):
            return rscode_response(RsCode.ARGS_ERROR, new_msg="账号或密码只能由字母、数字、下划线和句点组成")

        if Account.query.filter(Account.username == username, Account.password == password).count():
            return rscode_response(RsCode.OTHER_ERR, new_msg="账号已存在")

        if gender not in ("男", "女"):
            return rscode_response(RsCode.ARGS_ERROR)

        if not check_safe_nickname(nickname):
            return rscode_response(RsCode.ARGS_ERROR, new_msg="昵称只能由汉字、字母、数字、下划线和句点组成")

        if Player.query.filter(Player.nickname == nickname).count():
            return rscode_response(RsCode.OTHER_ERR, new_msg="昵称已存在")

        # 创建账号
        account = Account(username=username, password=password)
        db.session.add(account)
        db.session.flush()
        # 创建玩家
        player = Player(nickname=nickname, gender=gender, account_id=account.id)
        init_player(player)
        db.session.add(player)
        if not safe_commit(db):
            return rscode_response(RsCode.SERVER_BUSY)

        return rscode_response()
